using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.ServiceModel;
using System.Threading;
using AutoMapper;
using Core;
using IglooCoder.Commons.WcfNhibernate;
using Infrastucture;
using WcfService1.DTO;
using Omu.ValueInjecter;

namespace WcfService1
{
    // NOTE: You can use the "Rename" command on the "Refactor" PreSalesOrder to change the class name "PreSalesOrderServices" in code, svc and config file together.
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    [NHibernateContext]
    public class PreSalesOrderServices : IPreSalesOrderServices
    {
        private readonly PreSalesOrderRepository PreSalesOrderRepository;
        private readonly SalesOrderRepository SORepository;
        private readonly SalesInvoiceRepository SIRepository;
        private WcfSessionStorage _session;
        public PreSalesOrderServices()
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            _session = new WcfSessionStorage();
            PreSalesOrderRepository = new PreSalesOrderRepository(_session);
            SORepository = new SalesOrderRepository(_session);
            SIRepository = new SalesInvoiceRepository(_session);
        }

        #region IPreSalesOrderServices Members

        public List<PreSalesOrderDTO> GetList(int page, out long recordCount, string sortProperty = null,
                                              string sortType = "ASC")
        {
            var PreSalesOrders = new List<PreSalesOrder>();
            var Results = new List<PreSalesOrderDTO>();

            if (string.IsNullOrEmpty(sortProperty))
            {
                PreSalesOrders = PreSalesOrderRepository.GetDataPaged(page, 30, "SRDate", "DESC").ToList();
            }
            else
            {
                PreSalesOrders = PreSalesOrderRepository.GetDataPaged(page, 30, sortProperty, sortType).ToList();
            }

            recordCount = PreSalesOrderRepository.RecordCount;

            foreach (var preSalesOrder in PreSalesOrders)
            {
                var preSalesDTO = new PreSalesOrderDTO();
                preSalesDTO.PSNo = preSalesOrder.PSNo;
                preSalesDTO.SRDate = preSalesOrder.SRDate;
                preSalesDTO.CustomerName = preSalesOrder.CustomerName;
                preSalesDTO.Description = preSalesOrder.Description;
                preSalesDTO.SiNo = preSalesOrder.SINo;
                preSalesDTO.SoNo = preSalesOrder.SONo;
                preSalesDTO.DONo = preSalesOrder.DONo;
                preSalesDTO.Status = (Status)preSalesOrder.Status;
                Results.Add(preSalesDTO);
            }
           

            return Results;
        }

        public bool Save(PreSalesOrderDTO PreSalesOrderDTO)
        {
            bool res;
            try
            {
                PreSalesOrderRepository
                    .ExecuteTransactionNative(() =>
                                                  {
                                                      PreSalesOrder PreSalesOrder = PreSalesOrderRepository.GetDataOne(p => p.PSNo == PreSalesOrderDTO.PSNo);

                                                      if (PreSalesOrder == null)
                                                      {
                                                          PreSalesOrder = new PreSalesOrder();
                                                          PreSalesOrderDTO.created_date = DateTime.Now;
                                                          Mapper.Map(PreSalesOrderDTO, PreSalesOrder);
                                                          //Untuk New entry dari transaksi bukan dari email
                                                          if (String.IsNullOrEmpty(PreSalesOrder.PSNo))
                                                              PreSalesOrder.PSNo = GetLastSRNo();
                                                          foreach (PreSalesOrderDetail preSalesOrderDetail in PreSalesOrder.PreSalesOrderDetails)
                                                          {
                                                              preSalesOrderDetail.PreSalesOrder = PreSalesOrder;
                                                              preSalesOrderDetail.PreSalesOrderDetailId = 0;
                                                          }
                                                          PreSalesOrderRepository.SaveOrUpdate(PreSalesOrder);
                                                      }
                                                      else
                                                      {

                                                          //Jika Status Void dan Close tdk boleh Update
                                                          if (PreSalesOrder.Status == (int)Status.Void || PreSalesOrder.Status == (int)Status.Close)
                                                              throw new Exception("Tidak bisa di Update Status sudah Close atau Void!");
                                                          PreSalesOrderRepository.Delete(PreSalesOrder);
                                                          var PS = new PreSalesOrder();
                                                          PS.modified_date = DateTime.Now;
                                                          PS.created_date =
                                                              PreSalesOrder.created_date;
                                                          Mapper.Map(PreSalesOrderDTO, PS);
                                                          foreach (PreSalesOrderDetail preSalesOrderDetail in PS.PreSalesOrderDetails)
                                                              preSalesOrderDetail.PreSalesOrder = PS;
                                                          PreSalesOrderRepository.Session.SaveOrUpdateCopy(PS);

                                                      }
    
                                                  });
                
                res = true;
            }
            catch (Exception ex)
            {
                res = false;
                throw ex;
            }

            return res;
        }


        public bool Delete(PreSalesOrderDTO PreSalesOrderDto)
        {
            bool res;
            try
            {
                PreSalesOrder PreSalesOrder = PreSalesOrderRepository.GetDataOne(x => x.PSNo == PreSalesOrderDto.PSNo);
                PreSalesOrderRepository.Delete(PreSalesOrder);
                res = true;
            }
            catch (Exception)
            {
                res = false;
            }

            return res;
        }


        public List<PreSalesOrderDTO> GetListByCriteria(Dictionary<String, Object> criteria, string expression, int page,
                                                        out long recordCount)
        {
            var PreSalesOrders = new List<PreSalesOrder>();
            var Results = new List<PreSalesOrderDTO>();
            PreSalesOrders = PreSalesOrderRepository.GetDataPaged(criteria, expression, page, 30).ToList();
            recordCount = PreSalesOrderRepository.RecordCount;
            foreach (var preSalesOrder in PreSalesOrders)
            {
                var preSalesDTO = new PreSalesOrderDTO();
                preSalesDTO.PSNo = preSalesOrder.PSNo;
                preSalesDTO.SRDate = preSalesOrder.SRDate;
                preSalesDTO.CustomerName = preSalesOrder.CustomerName;
                preSalesDTO.Description = preSalesOrder.Description;
                preSalesDTO.SiNo = preSalesOrder.SINo;
                preSalesDTO.SoNo = preSalesOrder.SONo;
                preSalesDTO.DONo = preSalesOrder.DONo;
                preSalesDTO.Status = (Status)preSalesOrder.Status;
                Results.Add(preSalesDTO);
            }
           

            return Results;
        }


        public List<PreSalesOrderDTO> GetAllPreSalesOrder()
        {
            List<PreSalesOrder> PreSalesOrders =
                PreSalesOrderRepository.GetDataList(x => x.Status == Convert.ToInt16(Status.Open)).ToList();
            IEnumerable<PreSalesOrderDTO> Results = from p in PreSalesOrders
                                                    select new PreSalesOrderDTO {PSNo = p.PSNo,SRDate = p.SRDate};
            return Results.ToList();
        }


        public PreSalesOrderDTO GetPreSalesOrder(String kodePreSalesOrder)
        {
            PreSalesOrder preSalesOrder = PreSalesOrderRepository.GetDataOne(x => x.PSNo == kodePreSalesOrder);
            var preSalesOrderDto = new PreSalesOrderDTO();
            preSalesOrderDto.InjectFrom<CloneInjection>(preSalesOrder);
            return preSalesOrderDto;
        }

        public List<PreSalesOrderDTO> GetPreSalesOrderList(string kodePreSalesOrder)
        {
            List<PreSalesOrder> PreSalesOrders =
                PreSalesOrderRepository.GetDataList(x => x.PSNo.Contains(kodePreSalesOrder)).ToList();
            var Results = new List<PreSalesOrderDTO>();
            PreSalesOrders.ForEach(x =>
                                       {
                                           var preSalesOrderDto = new PreSalesOrderDTO();
                                           preSalesOrderDto.InjectFrom<CloneInjection>(x);
                                           Results.Add(preSalesOrderDto);
                                       }
                );

            return Results;
        }


        public bool DeleteDetail(PreSalesOrderDetailDTO PreSalesOrderDetailDTO)
        {
            bool res;
            try
            {
                var PreSalesOrderDetail =
                    PreSalesOrderRepository.Session.Get<PreSalesOrderDetail>(
                        PreSalesOrderDetailDTO.PreSalesOrderDetailId);
                PreSalesOrderRepository.DeleteDetail(PreSalesOrderDetail, PreSalesOrderDetail.PreSalesOrderDetailId);
                res = true;
            }
            catch (Exception)
            {
                res = false;
            }

            return res;
        }

        public string GetLastSRNo()
        {
            var appParamServices = new AppParamServices();
            AppParamDTO param = appParamServices.GetAppParamList("KodePS").FirstOrDefault();
            string res = PreSalesOrderRepository.GetMaxNumber(param.AppParamValue);

            if (string.IsNullOrEmpty(res))
                res = param.AppParamValue;

            string formatSO = "0000";
            string kodeSO;
            string lastNo = string.Empty;
            if (res.Length <= 4)
            {
                lastNo = formatSO;
                kodeSO = res;
            }
            else
            {
                lastNo = res.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[2];
                kodeSO = res.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries)[0];
            }

            string soNum = formatSO.Substring(0, formatSO.Length - (int.Parse(lastNo) + 1).ToString().Length) +
                           (int.Parse(lastNo) + 1);
            return kodeSO + "/" + DateTime.Now.Year + "/" + soNum;
        }

        public bool SendEmail(PreSalesOrderDTO preSalesOrderDto, String DestinationFolder)
        {
            var mailServices = new MailServices();
            PreSalesOrder Presales = PreSalesOrderRepository.GetDataOne(x => x.PSNo == preSalesOrderDto.PSNo);
            preSalesOrderDto = Mapper.Map(Presales, preSalesOrderDto);
            return mailServices.SendEmail(preSalesOrderDto,DestinationFolder);
        }

        #endregion
    }
}